package com.ermax.aircond.maintain.web.bean;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.richfaces.event.FileUploadEvent;
import org.richfaces.model.UploadedFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import com.ermax.aircond.maintain.domain.Building;
import com.ermax.aircond.maintain.domain.Floor;
import com.ermax.aircond.maintain.domain.FloorPlan;
import com.ermax.aircond.maintain.domain.Machine;
import com.ermax.aircond.maintain.service.MaintainService;
import com.ermax.aircond.resource.MessageBundle;
import com.ermax.aircond.util.service.MimeTypeService;


@Scope("view")
@Component
public class FloorPlanMaintainBean implements java.io.Serializable {

	private static final long serialVersionUID = 1L;

	private static final Logger logger = LoggerFactory.getLogger(FloorPlanMaintainBean.class);

	@Resource(name = "maintainService")
	private MaintainService maintainService;
	
	@Resource(name="mimeTypeService")
	private MimeTypeService mimeTypeService;

	private Floor selectedFloor = null;
	private FloorPlan floorPlan = null;
	private List<SelectItem> buildingOptions = new ArrayList<SelectItem>();
	private List<SelectItem> floorOptions = new ArrayList<SelectItem>();
	private List<Machine> machines = new ArrayList<Machine>();
	private long selectedBuildingId;
	private long selectedFloorId;
	
	private static final String STATUS_INIT = "INIT";
	private static final String STATUS_SEARCH = "SEARCH";
	
	private String status = "";
	
	@PostConstruct
	public void init() {
		try {
			reset();
		} catch (Exception ex) {
			String message = MessageBundle.getInstance().getMessage("error_init_fail", FacesContext.getCurrentInstance().getViewRoot().getLocale());
			FacesMessage facesMessage = new FacesMessage(message);
			FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		}
	}


	private void reset() {
		buildingOptions = createBuildingOptions();
		floorOptions = createFloorOptions();
		floorPlan = null;
		status = STATUS_INIT;
	}
	
	public void search(){
		if(selectedFloorId > 0){
			try {
				selectedFloor = maintainService.getFloorDetail(selectedFloorId);
				floorPlan = selectedFloor.getFloorPlan();
				machines = maintainService.getMachines(selectedFloor);
				status = STATUS_SEARCH;
			} catch (Exception e) {				
				logger.error(e.getMessage());
			}
		}
	}
	
	public void save(){
		UserDetails userDetails =  (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		Iterator<Machine> iter = machines.iterator();
		while(iter.hasNext()){
			Machine machine = iter.next();
			try {
				maintainService.updateMachine(machine, userDetails.getUsername());
			} catch (Exception e) {
				String message = MessageBundle.getInstance().getMessage("error_update_fail", FacesContext.getCurrentInstance().getViewRoot().getLocale()); 
				FacesMessage facesMessage  = new FacesMessage(message);
				FacesContext.getCurrentInstance().addMessage(null,facesMessage);
				return;
			}
		}
		String message = MessageBundle.getInstance().getMessage("info_apply_success", FacesContext.getCurrentInstance().getViewRoot().getLocale()); 
		FacesMessage facesMessage  = new FacesMessage(message);
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);
		
	}
	
	private List<SelectItem> createBuildingOptions() {
		List<SelectItem> results = new ArrayList<SelectItem>();		
		try {
			List<Building> buildings = maintainService.getAllBuildings();
			for (Building building : buildings) {
				SelectItem item = new SelectItem(building.getBuildingId(), building.getBuildingName());
				results.add(item);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}

		return results;
	}
	
	public void buildingValueChanged(ValueChangeEvent event) {      
        if (null != event.getNewValue()) {            
        	selectedFloorId = 0;        	
            selectedBuildingId = (Long) event.getNewValue();            
            floorOptions = createFloorOptions();            
        }
    }
	
	private List<SelectItem> createFloorOptions(){		
		selectedFloorId = 0;
		List<SelectItem> results = new ArrayList<SelectItem>();
		
		if(selectedBuildingId == 0){
			if(buildingOptions.size() > 0){
				SelectItem buildingItem = buildingOptions.get(0);
				selectedBuildingId = (Long) buildingItem.getValue();
			}
		}
		try{
			Building selectedBuilding = maintainService.getBuildingById(selectedBuildingId);
			List<Floor> floors = maintainService.getFloors(selectedBuilding);
        	for(Floor floor : floors){
        		SelectItem item = new SelectItem(floor.getFloorId(), floor.getFloorName());
        		results.add(item);
        	}
		}catch (Exception e) {
			logger.error(e.getMessage());
		}
		
		
		return results;
		
	}


	public List<SelectItem> getBuildingOptions() {
		return buildingOptions;
	}


	public void setBuildingOptions(List<SelectItem> buildingOptions) {
		this.buildingOptions = buildingOptions;
	}


	public List<SelectItem> getFloorOptions() {
		return floorOptions;
	}


	public void setFloorOptions(List<SelectItem> floorOptions) {
		this.floorOptions = floorOptions;
	}


	public long getSelectedBuildingId() {
		return selectedBuildingId;
	}


	public void setSelectedBuildingId(long selectedBuildingId) {
		this.selectedBuildingId = selectedBuildingId;
	}


	public long getSelectedFloorId() {
		return selectedFloorId;
	}


	public void setSelectedFloorId(long selectedFloorId) {
		this.selectedFloorId = selectedFloorId;
	}


	public List<Machine> getMachines() {
		return machines;
	}


	public void setMachines(List<Machine> machines) {
		this.machines = machines;
	}


	public FloorPlan getFloorPlan() {
		return floorPlan;
	}


	public void setFloorPlan(FloorPlan floorPlan) {
		this.floorPlan = floorPlan;
	}


	public String getStatus() {
		return status;
	}


	public void setStatus(String status) {
		this.status = status;
	}


	public Floor getSelectedFloor() {
		return selectedFloor;
	}


	public void setSelectedFloor(Floor selectedFloor) {
		this.selectedFloor = selectedFloor;
	}
	
	

}
